<template>
  <div class="page-user-profile">
    <!-- @click-right:van-nav-bar组件提供的API，给右侧的 文字信息 设置的单击事件 -->
    <van-nav-bar
      left-arrow
      @click-left="$router.back()"
      title="编辑资料"
      right-text="保存"
      @click-right="save()"
    ></van-nav-bar>

    <!-- 用户详细信息展示区域 -->
    <van-cell-group>
      <!-- center:使得单元格内容，垂直方向居中显示 -->
      <van-cell title="头像" is-link center @click="showPhoto=true">
        <!--
            slot="default" 自定义单元格右侧内容
            fit="cover"  图片填充模式 保持宽高缩放图片，使图片的短边能完全显示出来，裁剪长边
        -->
        <van-image slot="default" :src="userProfile.photo" round width="56" height="56" fit="cover"></van-image>
      </van-cell>
      <!-- value=xxx 设置单元格右侧内容部分 -->
      <van-cell title="名称" is-link :value="userProfile.name" @click="showName=true"></van-cell>
      <van-cell title="性别" is-link :value="userProfile.gender===0?'男':'女'" @click="showSex=true"></van-cell>
      <van-cell title="生日" is-link :value="userProfile.birthday" @click="showBirthday=true"></van-cell>
    </van-cell-group>

    <!-- 头像弹出层 -->
    <van-popup v-model="showPhoto" position="bottom">
      <!-- 间接触发的click事件，通过$refs获取到的dom节点 -->
      <van-cell title="本地相册选择图片" is-link @click="$refs.mypic.click()"></van-cell>
      <van-cell title="拍照" is-link></van-cell>
    </van-popup>

    <!-- 图像上传的表单域--隐藏状态 -->
    <!-- ref的目的是：为了获得当前的表单dom节点 this.$refs.mypic -->
    <!-- 也可通过id获取 document.getElementById('pic') -->
    <!-- 点击“本地相册选择图片”的时候，间接触发该表单域的click事件的执行，实现图片的上传功能 -->
    <!-- 通过@change事件，来感知表单域的变化 -->
    <input type="file" ref="mypic" id="pic" @change="startUpload()" style="display:none" />

    <!-- 名称弹出层 -->
    <van-popup v-model="showName" position="bottom">
      <!-- 编辑用户昵称  双向绑定用户的昵称-->
      <van-field v-model.trim="userProfile.name" type="textarea" rows="3"></van-field>
    </van-popup>

    <!-- 性别弹出层(上拉菜单) -->
    <!-- van-action-sheet"菜单"弹出层组件
         与普通弹出层的区别就是，只可以设置"菜单"项目，
    而普通弹出层可以自定义展示内容-->

    <!-- v-model="showSex":设置弹出是否显示的
         :actions="actions"：设置上拉菜单项目的 [{ name: '男' }, { name: '女' }] 格式固定，name固定
         @select="onSelect":单击某一个菜单项目时的回调处理函数
         cancel-text="取消":取消按钮的设置
    -->
    <van-action-sheet v-model="showSex" :actions="sexMenus" cancel-text="取消" @select="onSelect" />

    <!-- 生日弹出层 -->
    <van-popup v-model="showBirthday" position="bottom">
      <!-- 时间选择器
             v-model：默认激活当前时间的显示
             type 时间类型，年月日
             :min-date="minDate" 允许选取的最小时间
             @cancel 单击取消按钮回调事件
             @confirm 单击确认按钮后的回调处理函数，确认选取时间的，不要加() 括号
             注意点：时间选择器要求，所有的时间类型都必须是 new Date() 类型的
             所以，需将用户的生日信息，转换为 new Date() 类型的
      -->
      <van-datetime-picker
        v-model="currentDate"
        type="date"
        :min-date="minDate"
        :max-date="maxDate"
        @confirm="confirmDate"
        @cancel="showBirthday=false"
      ></van-datetime-picker>
    </van-popup>
  </div>
</template>

<script>
// 导入下载好的dayjs模块
import dayjs from 'dayjs'

// 导入获取用户个人资料的api函数
// 导入上传用户头像的api函数
import {
  apiUserProfile,
  apiUserPhoto,
  apiUserSaveProfile
} from '@/api/user.js'

export default {
  name: 'user-profile',
  data () {
    return {
      showPhoto: false, // 头像弹出层显示开关
      showName: false, // 名称弹出层显示开关
      showSex: false, // 性别弹出层显示开关

      showBirthday: false, // 生日弹出层显示开关
      currentDate: new Date(), // 当前默认显示的时间
      minDate: new Date(1900, 0, 1), // 最小时间选取(月份是从0开始)
      maxDate: new Date(2100, 0, 1), // 最大时间选取(月份是从0开始)

      // 性别上拉菜单的配置选项，语法结构固定，name属性固定
      sexMenus: [{ name: '男' }, { name: '女' }],

      // 用户的个人资料对象信息集
      userProfile: {
        photo: '',
        name: '',
        gender: '',
        birthday: ''
      }
    }
  },
  created () {
    this.getUserProfile()
  },
  methods: {
    // 开始上传头像---------------------------------------------------------
    // 头像图片选取好后，该函数会感知到，并自动执行
    async startUpload () {
      // console.dir(this.$refs.mypic) // 输出的是上传图片的表单域对象，里面有一个成员files
      // 1.获得上传好的图片对象
      const fdObj = this.$refs.mypic.files[0]

      // 2.把图片对象，整合到FormData里
      const fd = new FormData()
      // fd整合fbObj
      // photo:是接口文章要求的参数名称
      fd.append('photo', fdObj)

      // 3.把处理好的FormData给到api函数，提交给服务器端，做处理
      const result = await apiUserPhoto(fd)

      // 关闭弹出层
      this.showPhoto = false

      // 把上传好的，并且返回的头像信息更新显示到页面上
      // 本质是：给到userProfile.photo
      this.userProfile.photo = result.photo

      // 成功提示
      this.$toast.success('头像更新成功')
    },

    //  时间选择器 被单击“确定”按钮后的回调处理---------------------------------------
    confirmDate (val) {
      // val:固定代表 选择好的时间信息
      // console.log(val) // Sat Mar 09 2019 00:00:00 GMT+0800 (中国标准时间)
      // console.log(typeof val) // object
      // 表单中收集的时间要求是 年-月-日 格式形式的， 但现在我们拥有的是对象格式的
      // 表单不能收集对象格式的，所以需转化格式：object对象--->转化为 “年-月-日”
      // 不能使用Vue过滤器，因为其是模板技术
      // 通过dayjs把val转换为 年-月-日 格式
      // console.log(dayjs(val)) // dayjs对象
      this.userProfile.birthday = dayjs(val).format('YYYY-MM-DD')

      // 关闭弹出层
      this.showBirthday = false
    },

    // 性别上拉菜单选中项目时的回调处理函数-----------------------------------
    // val:代表选中的某一个菜单项目 {name:xxx}
    onSelect (val) {
      // console.log(val) // {name:'男'}
      // 对val做处理，赋值给data中的gander成员，只接受数据类型的
      this.userProfile.gender = val.name === '男' ? 0 : 1
      this.showSex = false // 隐藏上拉菜单
    },
    // 获取用户的个人资料信息------------------------------------------
    async getUserProfile () {
      this.userProfile = await apiUserProfile()
      // 把用户的真实生日转换为 new Date() 格式的，赋值给currentDate
      // 使得选择器 默认显示
      this.currentDate = new Date(this.userProfile.birthday)
    },

    // 点击“保存”按钮时的函数--------------------------------------------------
    async save () {
      // 保存用户的更新资料
      await apiUserSaveProfile(this.userProfile)

      // 提示信息
      this.$toast.success('更新用户资料成功')
    }
  }
}
</script>

<style scoped lang='less'></style>
